let rec power x n =
  if n <= 0 then
    invalid_arg "n <= 0"
  else if n = 1 then
    x
  else
    x * power x (n-1);;

let rec application poly x =
  match poly with
      [] -> 0
    | (x1,n1)::reste_poly -> x1*(power x n1) + application reste_poly x ;;

let rec add poly1 poly2 = match (poly1,poly2) with
    ([],poly) -> poly
  | (poly,[]) -> poly
  | (((x1,n1)::poly1),((x2,n2)::poly2)) when n1 = n2 -> ((x1+x2),n1)::(add poly1 poly2)
  | (((x1,n1)::poly1),((x2,n2)::poly2)) when n1 < n2 -> (x1,n1)::(add poly1 ((x2,n2)::poly2))
  | (((x1,n1)::poly1),((x2,n2)::poly2)) -> (x2,n2)::(add ((x1,n1)::poly1) poly2);;

let rec soustract poly1 poly2 = match (poly1,poly2) with
    ([],poly) -> poly
  | (poly,[]) -> poly
  | (((x1,n1)::poly1),((x2,n2)::poly2)) when n1 = n2 -> ((x1-x2),n1)::(soustract poly1 poly2)
  | (((x1,n1)::poly1),((x2,n2)::poly2)) when n1 < n2 -> (x1,n1)::(soustract poly1 ((-x2,n2)::poly2))
  | (((x1,n1)::poly1),((x2,n2)::poly2)) -> (x2,n2)::(soustract ((x1,n1)::poly1) poly2);;

let rec deriv poly = match poly with
    [] -> poly
  | (x1,n1)::reste_poly -> ((x1*n1),(n1-1))::(deriv reste_poly);;
